package com.taiyi.sqltoy.starter.handler;

import com.taiyi.sqltoy.starter.context.UserContext;
import com.taiyi.sqltoy.starter.properties.TaiyiSqlToyPlusProperties;
import lombok.extern.slf4j.Slf4j;
import org.sagacity.sqltoy.config.annotation.Entity;
import org.sagacity.sqltoy.config.model.OperateType;
import org.sagacity.sqltoy.model.IgnoreCaseSet;
import org.sagacity.sqltoy.plugins.IUnifyFieldsHandler;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * Taiyi 统一字段自动填充处理器
 * 支持creator、updater、tenant_id等字段的自动填充
 * 支持配置不需要租户过滤的表列表
 * 
 * @author taiyi
 * @since 1.0.0
 */
@Slf4j
public class TaiyiUnifyFieldsHandler implements IUnifyFieldsHandler {

    private final TaiyiSqlToyPlusProperties properties;
    private final UserContext userContext;

    public TaiyiUnifyFieldsHandler(TaiyiSqlToyPlusProperties properties, UserContext userContext) {
        this.properties = properties;
        this.userContext = userContext;
        log.info("Taiyi SqlToy Plus 统一字段处理器已初始化");
        log.info("- 启用统一字段: {}", properties.isEnableUnifyFields());
        log.info("- 启用多租户: {}", properties.isEnableMultiTenant());
        log.info("- 租户字段: {}", properties.getTenantField());
        log.info("- 忽略租户过滤的表: {}", properties.getIgnoreTenantTables());
    }

    @Override
    public Map<String, Object> createUnifyFields() {
        if (!properties.isEnableUnifyFields()) {
            return new HashMap<>();
        }

        Map<String, Object> unifyFields = new HashMap<>();
        
        // 获取当前用户信息
        String currentUserId = getCurrentUserId();
        String currentTenantId = getCurrentTenantId();
        
        TaiyiSqlToyPlusProperties.UnifyFields config = properties.getUnifyFields();
        
        // 设置创建人字段
        if (StringUtils.hasText(config.getCreatorField())) {
            unifyFields.put(config.getCreatorField(), currentUserId);
        }
        
        // 设置更新人字段（插入时创建人和更新人相同）
        if (StringUtils.hasText(config.getUpdaterField())) {
            unifyFields.put(config.getUpdaterField(), currentUserId);
        }
        
        // 设置创建时间字段
        if (config.isEnableCreateTime() && StringUtils.hasText(config.getCreateTimeField())) {
            unifyFields.put(config.getCreateTimeField(), new Timestamp(System.currentTimeMillis()));
        }
        
        // 设置更新时间字段
        if (config.isEnableUpdateTime() && StringUtils.hasText(config.getUpdateTimeField())) {
            unifyFields.put(config.getUpdateTimeField(), new Timestamp(System.currentTimeMillis()));
        }
        
        // 设置租户ID字段
        if (properties.isEnableMultiTenant() && StringUtils.hasText(properties.getTenantField())) {
            // 数据库字段名
            unifyFields.put(properties.getTenantField(), currentTenantId);
            // Java字段名（兼容驼峰命名）
            String camelCaseTenantField = toCamelCase(properties.getTenantField());
            if (!camelCaseTenantField.equals(properties.getTenantField())) {
                unifyFields.put(camelCaseTenantField, currentTenantId);
            }
        }
        
        if (log.isDebugEnabled()) {
            log.debug("创建统一字段: {}", unifyFields);
        }
        
        return unifyFields;
    }

    @Override
    public Map<String, Object> updateUnifyFields() {
        if (!properties.isEnableUnifyFields()) {
            return new HashMap<>();
        }

        Map<String, Object> unifyFields = new HashMap<>();
        
        // 获取当前用户信息
        String currentUserId = getCurrentUserId();
        
        TaiyiSqlToyPlusProperties.UnifyFields config = properties.getUnifyFields();
        
        // 设置更新人字段
        if (StringUtils.hasText(config.getUpdaterField())) {
            unifyFields.put(config.getUpdaterField(), currentUserId);
        }
        
        // 设置更新时间字段
        if (config.isEnableUpdateTime() && StringUtils.hasText(config.getUpdateTimeField())) {
            unifyFields.put(config.getUpdateTimeField(), new Timestamp(System.currentTimeMillis()));
        }
        
        if (log.isDebugEnabled()) {
            log.debug("更新统一字段: {}", unifyFields);
        }
        
        return unifyFields;
    }

    @Override
    public IgnoreCaseSet forceUpdateFields() {
        IgnoreCaseSet forceFields = new IgnoreCaseSet();
        
        if (properties.isEnableUnifyFields()) {
            TaiyiSqlToyPlusProperties.UnifyFields config = properties.getUnifyFields();
            
            // 默认强制更新updater字段
            if (StringUtils.hasText(config.getUpdaterField())) {
                forceFields.add(config.getUpdaterField());
            }
            
            // 默认强制更新时间字段
            if (config.isEnableUpdateTime() && StringUtils.hasText(config.getUpdateTimeField())) {
                forceFields.add(config.getUpdateTimeField());
            }
            
            // 添加配置的强制更新字段
            config.getForceUpdateFields().forEach(forceFields::add);
        }
        
        return forceFields;
    }

    @Override
    public String[] authTenants(Class entityClass, OperateType operType) {
        if (!properties.isEnableMultiTenant()) {
            return null;
        }
        
        // 检查是否为忽略租户过滤的表
        if (shouldIgnoreTenantFilter(entityClass)) {
            if (log.isDebugEnabled()) {
                log.debug("表 {} 在忽略租户过滤列表中，跳过租户过滤", getTableName(entityClass));
            }
            return null;
        }
        
        String currentTenantId = getCurrentTenantId();
        if (StringUtils.hasText(currentTenantId)) {
            return new String[]{currentTenantId};
        }
        
        log.warn("当前租户ID为空，可能影响数据安全");
        return null;
    }

    @Override
    public String getUserTenantId() {
        return getCurrentTenantId();
    }

    /**
     * 获取当前用户ID
     */
    private String getCurrentUserId() {
        if (userContext != null && userContext.hasCurrentUser()) {
            String userId = userContext.getCurrentUserId();
            if (StringUtils.hasText(userId)) {
                return userId;
            }
            // 如果用户ID为空，尝试使用用户名
            String username = userContext.getCurrentUsername();
            if (StringUtils.hasText(username)) {
                return username;
            }
        }
        
        // 返回默认值
        return properties.getUnifyFields().getDefaultCreator();
    }

    /**
     * 获取当前租户ID
     */
    private String getCurrentTenantId() {
        if (userContext != null && userContext.hasCurrentUser()) {
            String tenantId = userContext.getCurrentTenantId();
            if (StringUtils.hasText(tenantId)) {
                return tenantId;
            }
        }
        
        // 返回默认值
        return properties.getDefaultTenantId();
    }

    /**
     * 判断是否应该忽略租户过滤
     */
    private boolean shouldIgnoreTenantFilter(Class entityClass) {
        if (!properties.isEnableMultiTenant() || properties.getIgnoreTenantTables().isEmpty()) {
            return false;
        }
        
        String tableName = getTableName(entityClass);
        return properties.getIgnoreTenantTables().contains(tableName);
    }

    /**
     * 获取实体类对应的表名
     */
    private String getTableName(Class entityClass) {
        if (entityClass == null) {
            return "";
        }
        
        // 检查是否有@Entity注解
        if (entityClass.isAnnotationPresent(Entity.class)) {
            Entity entityAnnotation = (Entity) entityClass.getAnnotation(Entity.class);
            String tableName = entityAnnotation.tableName();
            if (StringUtils.hasText(tableName)) {
                return tableName;
            }
        }
        
        // 使用类名转换为下划线命名
        return camelToUnderscore(entityClass.getSimpleName());
    }

    /**
     * 驼峰命名转下划线命名
     */
    private String camelToUnderscore(String camelCase) {
        if (!StringUtils.hasText(camelCase)) {
            return "";
        }
        
        StringBuilder result = new StringBuilder();
        result.append(Character.toLowerCase(camelCase.charAt(0)));
        
        for (int i = 1; i < camelCase.length(); i++) {
            char ch = camelCase.charAt(i);
            if (Character.isUpperCase(ch)) {
                result.append("_").append(Character.toLowerCase(ch));
            } else {
                result.append(ch);
            }
        }
        
        return result.toString();
    }

    /**
     * 下划线命名转驼峰命名
     */
    private String toCamelCase(String underscore) {
        if (!StringUtils.hasText(underscore)) {
            return "";
        }
        
        String[] parts = underscore.split("_");
        if (parts.length <= 1) {
            return underscore;
        }
        
        StringBuilder result = new StringBuilder(parts[0]);
        for (int i = 1; i < parts.length; i++) {
            String part = parts[i];
            if (StringUtils.hasText(part)) {
                result.append(Character.toUpperCase(part.charAt(0)));
                if (part.length() > 1) {
                    result.append(part.substring(1));
                }
            }
        }
        
        return result.toString();
    }
}